# game constants
from constants import *

# cocos componets used by this scene
from cocos.director import director
from cocos.scene import Scene
from cocos.layer import Layer, ColorLayer
from cocos.scenes.transitions import *
from cocos.actions import *
from cocos.sprite import Sprite
from cocos.text import Label

from cocos.tiles import RectMap, RectMapLayer, ScrollingManager, load
from cocos.draw import Line
from cocos.batch import BatchNode

# pyglet  componets used by this scene
import pyglet
from pyglet import gl, font
from pyglet.window import key

import random

from scene_mission import *
from dialog_build import *

class PlanetLayer(Layer):

    is_event_handler = True     #: enable pyglet's events

    def __init__(self, interface, planet):
        # call the parent's constructor
        super(PlanetLayer, self).__init__()

        # keep track of the interface
        self.interface = interface
        self.scaleFactor = SCREEN_HEIGHT/GALAXY_SIZE 
        
        # the planet on which this battle takes place
        self.planet = planet
        
        # just a uniform color background
        #self.add(ColorLayer(random.randint(0,255),40,40,200), z=-1)
                
        self._initMap()
                
        # add a label
        self.infoLabel = Label("Planet Screen",
            font_size=12,
            multiline=True,
            height=100,
            width=360,
            x=10,
            y=SCREEN_HEIGHT - 20,
            anchor_x=font.Text.LEFT,
            anchor_y=font.Text.TOP)
        self.add(self.infoLabel)
        
    def _initMap(self):
                
        # distance from edge of screen to beginning of planet grid        
        border = (SCREEN_HEIGHT-((len(self.planet.areas)**0.5)*24))*.5-24
               
        # generation of background layer
        # TODO: procedurally generate layer depending on planet type and amount of available resources
        self.surface = Sprite('resources/planet_surface.png', scale = 1/(600/(len(self.planet.areas)**0.5*48)))
        self.surface.position = 0.5/(600/(len(self.planet.areas)**0.5*48))*600+border-24, 0.5/(600/(len(self.planet.areas)**0.5*48))*600+border-24 # TODO: Make code easier to read, replace math with variables, window size independency
        # change color depending on planet type
        if self.planet.type == 0: # Ice
            self.surface.color = (51, 204, 255) 
        elif self.planet.type == 1: # Rock
            self.surface.color = (153, 153, 153)
        elif self.planet.type == 2: # Terran
            self.surface.color = (102, 153, 102) 
        elif self.planet.type == 3: # Jungle
            self.surface.color = (51, 153, 0) 
        elif self.planet.type == 4: # Desert
            self.surface.color = (255, 208, 148) 
        elif self.planet.type == 5: # Inferno
            self.surface.color = (204, 51, 0) 
        self.add(self.surface, z=-1)
                        
        # generation of grid layer
        # TODO: draw lines with OpenGL if it's less demanding or if it looks nicer
        self.gridBatchNode = BatchNode()
        self.add(self.gridBatchNode,z=0)
        
        tileSize = 8
        
        for coordinate in self.planet.areas:
            if self.planet.areas[coordinate].isCleared == True:
                sprite = Sprite('resources/grid.png')
            else:
                sprite = Sprite('resources/grid_fow.png')
                sprite.color = (102,0,0)
            sprite.position = border+(self.planet.areas[coordinate].x*tileSize*self.scaleFactor),border+(self.planet.areas[coordinate].y*tileSize*self.scaleFactor)
            self.gridBatchNode.add(sprite,name='mxa'+str(self.planet.areas[coordinate].x)+'mya'+str(self.planet.areas[coordinate].y))
        
        # generation of building tile layer
        self.buildingBatchNode = BatchNode()
        self.add(self.buildingBatchNode,z=1)
        
        tileSize = 8        

        # add building tiles
        for coordinate in self.planet.areas:
            if self.planet.areas[coordinate].building == BUILDING_BASE:
                sprite = Sprite('resources/base.png')
                sprite.position = border+(self.planet.areas[coordinate].x*tileSize*self.scaleFactor),border+(self.planet.areas[coordinate].y*tileSize*self.scaleFactor)
                self.buildingBatchNode.add(sprite,name='x'+str(self.planet.areas[coordinate].x)+'y'+str(self.planet.areas[coordinate].y))
            if self.planet.areas[coordinate].building == BUILDING_HOUSE:
                sprite = Sprite('resources/house.png')
                sprite.position = border+(self.planet.areas[coordinate].x*tileSize*self.scaleFactor),border+(self.planet.areas[coordinate].y*tileSize*self.scaleFactor)
                self.buildingBatchNode.add(sprite,name='x'+str(self.planet.areas[coordinate].x)+'y'+str(self.planet.areas[coordinate].y))
            if self.planet.areas[coordinate].building == BUILDING_FARM:
                sprite = Sprite('resources/farm.png')
                sprite.position = border+(self.planet.areas[coordinate].x*tileSize*self.scaleFactor),border+(self.planet.areas[coordinate].y*tileSize*self.scaleFactor)
                self.buildingBatchNode.add(sprite,name='x'+str(self.planet.areas[coordinate].x)+'y'+str(self.planet.areas[coordinate].y))
            if self.planet.areas[coordinate].building == BUILDING_MINE:
                sprite = Sprite('resources/mine.png')
                sprite.position = border+(self.planet.areas[coordinate].x*tileSize*self.scaleFactor),border+(self.planet.areas[coordinate].y*tileSize*self.scaleFactor)
                self.buildingBatchNode.add(sprite,name='x'+str(self.planet.areas[coordinate].x)+'y'+str(self.planet.areas[coordinate].y))
                


        # create a production overlay layer
        self.productionOverlay = ColorLayer(255,0,0,0)
        self.add(self.productionOverlay,z=2)

        # TODO?: move to global variable
        border = (SCREEN_HEIGHT-((len(self.planet.areas)**0.5)*24))*.5-48      
            
        for coordinate in self.planet.areas:
            #add labels for production overlay
            productionOverlayText = 'M: ' + str(self.planet.areas[coordinate].mineralYeld) + '\nF: ' + str(self.planet.areas[coordinate].organicYeld)
            self.productionOverlayLabel = Label(productionOverlayText,
                    font_size=10,
                    multiline=True,
                    height=48,
                    width=48,
                    x=border+self.planet.areas[coordinate].x*48,
                    y=border+self.planet.areas[coordinate].y*48+48,
                    anchor_x=font.Text.LEFT,
                    anchor_y=font.Text.TOP)
            self.productionOverlay.add(self.productionOverlayLabel)
            
            

    def toggleProductionOverlay(self):
        # toggles the production overlay.
        self.productionOverlay.visible = not self.productionOverlay.visible


    def on_enter(self):
        super(PlanetLayer, self).on_enter()   
        
        # shedule a function to update itself (the graphic) every frame
        self.schedule(self.update)      

        # probably here we want to shedule a slow updateGame()

    def on_exit(self):
        super(PlanetLayer, self).on_exit()   
        self.unschedule(self.update)
        
    def update(self,dt, *args, **kwargs):
        infoText = "Planet Screen "  + self.planet.name+"\n"
        infoText += "\n Press M to send a clear area mission"
        infoText += "\n Press SPACE to toggle production overlay"
        infoText += "\n Press ENTER to go back to galaxy screen"
        self.infoLabel.element.text = infoText

    def on_key_press(self, k , m):
        if k == key.M:
            area = random.choice(self.planet.areas.values())
            director.push(MissionScene(self.interface,area)) 
            
        if k == key.ENTER:
            # go back to galaxy
            self.unschedule(self.update)   
            director.pop() 
            
        if k == key.SPACE:
            # toggle production overlay
            self.toggleProductionOverlay()

        if k == key.ESCAPE:
            # this should prevent ESC to pop this scene
            return pyglet.event.EVENT_HANDLED

    def pickArea(self,screen_x,screen_y):
        
        # pick coordinate of area
        #pickedArea = self.planet.areas(x,y)

        return self.planet.areas[1,1]
        #return None  


    def on_mouse_press(self, x, y, buttons, modifiers):
        pickedArea = self.pickArea(x,y)
        self.add(BuildDialog(self,pickedArea),z=2)

# construct the scene here and return
# instead of doing this in the graphic interface (for example self.genericScene = Scene (GenericLayer()) )
# this is because here one can define more complicated scenes, independent of the interface
def PlanetScene(interface,area):
    # in this generic example, build a scene composed by only one layer
    return Scene( PlanetLayer(interface,area) )
